.TH std::atomic::exchange 3 "2024.06.10" "http://cppreference.com" "C++ Standard Libary"
.SH NAME
std::atomic::exchange \- std::atomic::exchange

.SH Synopsis
   T exchange( T desired, std::memory_order order =                   \fB(1)\fP \fI(since C++11)\fP
                              std::memory_order_seq_cst ) noexcept;
   T exchange( T desired, std::memory_order order =
                              std::memory_order_seq_cst ) volatile    \fB(2)\fP \fI(since C++11)\fP
   noexcept;

   Atomically replaces the underlying value with desired (a read-modify-write
   operation). Memory is affected according to the value of order.

   It is deprecated if std::atomic<T>::is_always_lock_free is false and   \fI(since C++20)\fP
   overload \fB(2)\fP participates in overload resolution.

.SH Parameters

   desired - value to assign
   order   - memory order constraints to enforce

.SH Return value

   The value of the atomic variable before the call.

.SH Example


// Run this code

 #include <algorithm>
 #include <atomic>
 #include <cstddef>
 #include <iostream>
 #include <syncstream>
 #include <thread>
 #include <vector>

 int main()
 {
     constexpr int thread_count{5};
     constexpr int sum{5};

     std::atomic<int> atom{0};
     std::atomic<int> counter{0};

     auto increment_to_sum = [&](const int id)
     {
         for (int next = 0; next < sum;)
         {
             // each thread is writing a value from its own knowledge
             const int current = atom.exchange(next);
             counter++;
             // sync writing to prevent from interrupting by other threads
             std::osyncstream(std::cout)
                 << "Thread #" << id << " (id=" << std::this_thread::get_id()
                 << ") wrote " << next << " replacing the old value "
                 << current << ".\\n";
             next = std::max(current, next) + 1;
         }
     };

     std::vector<std::thread> v;
     for (std::size_t i = 0; i < thread_count; ++i)
         v.emplace_back(increment_to_sum, i);

     for (auto& tr : v)
         tr.join();

     std::cout << thread_count << " threads take "
               << counter << " times in total to "
               << "increment 0 to " << sum << ".\\n";
 }

.SH Possible output:

 Thread #1 (id=139722332333824) wrote 0 replacing the old value 0.
 Thread #2 (id=139722323941120) wrote 0 replacing the old value 0.
 Thread #1 (id=139722332333824) wrote 1 replacing the old value 0.
 Thread #1 (id=139722332333824) wrote 2 replacing the old value 1.
 Thread #1 (id=139722332333824) wrote 3 replacing the old value 2.
 Thread #1 (id=139722332333824) wrote 4 replacing the old value 3.
 Thread #0 (id=139722340726528) wrote 0 replacing the old value 0.
 Thread #3 (id=139722315548416) wrote 0 replacing the old value 0.
 Thread #3 (id=139722315548416) wrote 1 replacing the old value 4.
 Thread #0 (id=139722340726528) wrote 1 replacing the old value 1.
 Thread #4 (id=139722307155712) wrote 0 replacing the old value 1.
 Thread #4 (id=139722307155712) wrote 2 replacing the old value 2.
 Thread #4 (id=139722307155712) wrote 3 replacing the old value 2.
 Thread #4 (id=139722307155712) wrote 4 replacing the old value 3.
 Thread #2 (id=139722323941120) wrote 1 replacing the old value 0.
 Thread #0 (id=139722340726528) wrote 2 replacing the old value 1.
 Thread #2 (id=139722323941120) wrote 2 replacing the old value 4.
 Thread #0 (id=139722340726528) wrote 3 replacing the old value 2.
 Thread #0 (id=139722340726528) wrote 4 replacing the old value 3.
 5 threads take 19 times in total to increment 0 to 5.

.SH See also

   atomic_exchange          atomically replaces the value of the atomic object with
   atomic_exchange_explicit non-atomic argument and returns the old value of the atomic
   \fI(C++11)\fP                  \fI(function template)\fP
   \fI(C++11)\fP
   exchange                 replaces the argument with a new value and returns its
   \fI(C++14)\fP                  previous value
                            \fI(function template)\fP
